home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP07.ZIP / CHAP07 / PATRON / DOCUMENT.CPP < prev    next >
C/C++ Source or Header  |  1993-06-07  |  22KB  |  1,019 lines

  1. /*
  2.  * DOCUMENT.CPP
  3.  * Modifications for Chapter 7
  4.  *
  5.  * Implementation of the CPatronDoc derivation of CDocument that
  6.  * manages pages for us.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include <memory.h>
  19. #include "patron.h"
  20.  
  21.  
  22.  
  23. /*
  24.  * CPatronDoc::CPatronDoc
  25.  * CPatronDoc::~CPatronDoc
  26.  *
  27.  * Constructor Parameters:
  28.  *  hInst           HINSTANCE of the application.
  29.  */
  30.  
  31. CPatronDoc::CPatronDoc(HINSTANCE hInst)
  32.     : CDocument(hInst)
  33.     {
  34.     m_pPG=NULL;
  35.     m_lVer=VERSIONCURRENT;
  36.     m_pIStorage=NULL;
  37.  
  38.     //CHAPTER7MOD
  39.     m_fPrintSetup=TRUE;
  40.     //End CHAPTER7MOD
  41.     return;
  42.     }
  43.  
  44.  
  45. CPatronDoc::~CPatronDoc(void)
  46.     {
  47.     if (NULL!=m_pPG)
  48.         delete m_pPG;
  49.  
  50.     if (NULL!=m_pIStorage)
  51.         m_pIStorage->Release();
  52.  
  53.     CoFreeUnusedLibraries();
  54.     return;
  55.     }
  56.  
  57.  
  58.  
  59.  
  60.  
  61. /*
  62.  * CPatronDoc::FInit
  63.  *
  64.  * Purpose:
  65.  *  Initializes an already created document window.  The client actually
  66.  *  creates the window for us, then passes that here for further
  67.  *  initialization.
  68.  *
  69.  * Parameters:
  70.  *  pDI             LPDOCUMENTINIT containing initialization parameters.
  71.  *
  72.  * Return Value:
  73.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  74.  */
  75.  
  76. BOOL CPatronDoc::FInit(LPDOCUMENTINIT pDI)
  77.     {
  78.     //Change the stringtable range to our customization.
  79.     pDI->idsMin=IDS_DOCUMENTMIN;
  80.     pDI->idsMax=IDS_DOCUMENTMAX;
  81.  
  82.     //Do default initialization
  83.     if (!CDocument::FInit(pDI))
  84.         return FALSE;
  85.  
  86.     //Pages are created when we get a ::ULoad later.
  87.     return TRUE;
  88.     }
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95. /*
  96.  * CPatronDoc::FMessageHook
  97.  *
  98.  * Purpose:
  99.  *  Processes WM_SIZE for the document so we can resize the Pages window.
  100.  *
  101.  * Parameters:
  102.  *  <WndProc Parameters>
  103.  *  pLRes           LRESULT FAR * in which to store the return value
  104.  *                  for the message.
  105.  *
  106.  * Return Value:
  107.  *  BOOL            TRUE to prevent further processing, FALSE otherwise.
  108.  */
  109.  
  110. BOOL CPatronDoc::FMessageHook(HWND hWnd, UINT iMsg, WPARAM wParam
  111.     , LPARAM lParam, LRESULT FAR *pLRes)
  112.     {
  113.     UINT        dx, dy;
  114.     RECT        rc;
  115.  
  116.     if (WM_SIZE==iMsg && NULL!=m_pPG)
  117.         {
  118.         dx=LOWORD(lParam);
  119.         dy=HIWORD(lParam);
  120.  
  121.         //Resize the Pages window to fit the new client area of the document
  122.         GetClientRect(hWnd, &rc);
  123.         m_pPG->RectSet(&rc, FALSE);
  124.         }
  125.  
  126.     /*
  127.      * We return FALSE even on WM_SIZE so we can let the default procedure
  128.      * handle maximized MDI child windows appropriately.
  129.      */
  130.     return FALSE;
  131.     }
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140. /*
  141.  * CPatronDoc::Clear
  142.  *
  143.  * Purpose:
  144.  *  Sets all contents in the document back to defaults with no filename.
  145.  *
  146.  * Paramters:
  147.  *  None
  148.  *
  149.  * Return Value:
  150.  *  None
  151.  */
  152.  
  153. void CPatronDoc::Clear(void)
  154.     {
  155.     //Completely reset the pages
  156.     m_pPG->FIStorageSet(NULL, FALSE, FALSE);
  157.  
  158.     CDocument::Clear();
  159.     m_lVer=VERSIONCURRENT;
  160.     return;
  161.     }
  162.  
  163.  
  164.  
  165.  
  166. //CHAPTER7MOD
  167.  
  168. /*
  169.  * CPatronDoc::FDirtyGet
  170.  *
  171.  * Purpose:
  172.  *  Returns the current dirty status of the document.
  173.  *
  174.  * Parameters:
  175.  *  None
  176.  *
  177.  * Return Value:
  178.  *  BOOL            TRUE if the file is clean, FALSE otherwise.
  179.  */
  180.  
  181. BOOL CPatronDoc::FDirtyGet()
  182.     {
  183.     BOOL    fPageDirty;
  184.  
  185.     fPageDirty=m_pPG->FIsDirty();
  186.     return m_fDirty | fPageDirty;
  187.     }
  188.  
  189.  
  190.  
  191.  
  192.  
  193. /*
  194.  * CPatronDoc::Delete
  195.  *
  196.  * Purpose:
  197.  *  Removed the current object from the document.
  198.  *
  199.  * Paramters:
  200.  *  None
  201.  *
  202.  * Return Value:
  203.  *  None
  204.  */
  205.  
  206. void CPatronDoc::Delete(void)
  207.     {
  208.     if (NULL!=m_pPG)
  209.         m_pPG->TenantDestroy();
  210.  
  211.     CoFreeUnusedLibraries();
  212.     return;
  213.     }
  214.  
  215.  
  216.  
  217.  
  218.  
  219. /*
  220.  * CPatronDoc::FQueryPrinterSetup
  221.  *
  222.  * Purpose:
  223.  *  Returns whether or not the Printer Setup menu item can be
  224.  *  enabled.  Once you create a tenant in any page, Printer Setup
  225.  *  is voided simply to keep this sample simple, that is, we don't
  226.  *  have to worry about reorganizing potentially large amounts
  227.  *  of layout after we start plopping down objects.
  228.  *
  229.  * Parameters:
  230.  *  None
  231.  *
  232.  * Return Value:
  233.  *  BOOL            TRUE to enable the menu, FALSE otherwise.
  234.  */
  235.  
  236. BOOL CPatronDoc::FQueryPrinterSetup(void)
  237.     {
  238.     return m_fPrintSetup;
  239.     }
  240.  
  241.  
  242.  
  243.  
  244.  
  245. /*
  246.  * CPatronDoc::FQueryObjectSelected
  247.  *
  248.  * Purpose:
  249.  *  Returns whether or not there is an object selected in this
  250.  *  document for Cut, Copy, Delete functions.
  251.  *
  252.  * Parameters:
  253.  *  hMenu           HMENU of the Edit menu.
  254.  *
  255.  * Return Value:
  256.  *  BOOL            TRUE if we have an object, FALSE otherwise.
  257.  */
  258.  
  259. BOOL CPatronDoc::FQueryObjectSelected(HMENU hMenu)
  260.     {
  261.     return m_pPG->FQueryObjectSelected(hMenu);
  262.     }
  263.  
  264.  
  265. //End CHAPTER7MOD
  266.  
  267.  
  268.  
  269. /*
  270.  * CPatronDoc::ULoad
  271.  *
  272.  * Purpose:
  273.  *  Loads a given document without any user interface overwriting the
  274.  *  previous contents of the editor.
  275.  *
  276.  * Parameters:
  277.  *  fChangeFile     BOOL indicating if we're to update the window title
  278.  *                  and the filename from using this file.
  279.  *  pszFile         LPSTR to the filename to load.  Could be NULL for
  280.  *                  an untitled document.
  281.  *
  282.  * Return Value:
  283.  *  UINT            An error value from DOCERR_*
  284.  */
  285.  
  286.  
  287. UINT CPatronDoc::ULoad(BOOL fChangeFile, LPSTR pszFile)
  288.     {
  289.     RECT        rc;
  290.     LPSTORAGE   pIStorage;
  291.     HRESULT     hr;
  292.     CLSID       clsID;
  293.     DWORD       dwMode=STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  294.  
  295.     if (NULL==pszFile)
  296.         {
  297.         //Create a new temp file.
  298.         hr=StgCreateDocfile(NULL, dwMode | STGM_CREATE | STGM_DELETEONRELEASE
  299.             , 0, &pIStorage);
  300.  
  301.         //Mark this as one of our class since we check with ReadClassStg below.
  302.         if (SUCCEEDED(hr))
  303.             WriteClassStg(pIStorage, CLSID_PatronPages);
  304.         }
  305.     else
  306.         {
  307.         hr=StgOpenStorage(pszFile, NULL, dwMode, NULL, 0, &pIStorage);
  308.         }
  309.  
  310.     if (FAILED(hr))
  311.         return DOCERR_COULDNOTOPEN;
  312.  
  313.     //Check if this is our type of file and exit if not.
  314.     hr=ReadClassStg(pIStorage, &clsID);
  315.  
  316.     if (FAILED(hr) || !IsEqualCLSID(clsID, CLSID_PatronPages))
  317.         {
  318.         pIStorage->Release();
  319.         return DOCERR_READFAILURE;
  320.         }
  321.  
  322.     //Attempt to create our contained Pages window.
  323.     m_pPG=new CPages(m_hInst, m_cf);
  324.     GetClientRect(m_hWnd, &rc);
  325.  
  326.     if (!m_pPG->FInit(m_hWnd, &rc, WS_CHILD | WS_VISIBLE, ID_PAGES, NULL))
  327.         {
  328.         pIStorage->Release();
  329.         return DOCERR_READFAILURE;
  330.         }
  331.  
  332.     if (!m_pPG->FIStorageSet(pIStorage, FALSE, (BOOL)(NULL==pszFile)))
  333.         {
  334.         pIStorage->Release();
  335.         return DOCERR_READFAILURE;
  336.         }
  337.  
  338.     m_pIStorage=pIStorage;
  339.     Rename(pszFile);
  340.  
  341.     //Do initial setup if this is a new file, otherwise Pages handles things.
  342.     if (NULL==pszFile)
  343.         {
  344.         //Go initialize the Pages for the default printer.
  345.         if (!PrinterSetup(NULL, TRUE))
  346.             return DOCERR_COULDNOTOPEN;
  347.  
  348.         //Go create an initial page.
  349.         m_pPG->PageInsert(0);
  350.         }
  351.     //CHAPTER7MOD
  352.     else
  353.         m_fPrintSetup=FALSE;    //Can't change an already saved configuration
  354.     //End CHAPTER7MOD
  355.  
  356.     FDirtySet(FALSE);
  357.     return DOCERR_NONE;
  358.     }
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366. /*
  367.  * CPatronDoc::USave
  368.  *
  369.  * Purpose:
  370.  *  Writes the file to a known filename, requiring that the user has
  371.  *  previously used FileOpen or FileSaveAs in order to have a filename.
  372.  *
  373.  * Parameters:
  374.  *  uType           UINT indicating the type of file the user requested
  375.  *                  to save in the File Save As dialog.
  376.  *  pszFile         LPSTR under which to save.  If NULL, use the current name.
  377.  *
  378.  * Return Value:
  379.  *  UINT            An error value from DOCERR_*
  380.  */
  381.  
  382. UINT CPatronDoc::USave(UINT uType, LPSTR pszFile)
  383.     {
  384.     HRESULT     hr;
  385.     LPSTORAGE   pIStorage;
  386.  
  387.     //Save or Save As with the same file is just a commit.
  388.     if (NULL==pszFile || (NULL!=pszFile && 0==lstrcmpi(pszFile, m_szFile)))
  389.         {
  390.         WriteFmtUserTypeStg(m_pIStorage, m_cf, PSZ(IDS_CLIPBOARDFORMAT));
  391.  
  392.         //Insure pages are up to date.
  393.         m_pPG->FIStorageUpdate(FALSE);
  394.  
  395.         //Commit everyting
  396.         m_pIStorage->Commit(STGC_ONLYIFCURRENT);
  397.  
  398.         FDirtySet(FALSE);
  399.         return DOCERR_NONE;
  400.         }
  401.  
  402.     /*
  403.      * When we're given a name, open the storage, creating it new if
  404.      * it does not exist or overwriting the old one.  Then ::CopyTo
  405.      * from the current to the new, ::Commit the new, then ::Release
  406.      * the old.
  407.      */
  408.  
  409.     hr=StgCreateDocfile(pszFile, STGM_TRANSACTED | STGM_READWRITE
  410.         | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage);
  411.  
  412.     if (FAILED(hr))
  413.         return DOCERR_COULDNOTOPEN;
  414.  
  415.     WriteClassStg(pIStorage, CLSID_PatronPages);
  416.     WriteFmtUserTypeStg(pIStorage, m_cf, PSZ(IDS_CLIPBOARDFORMAT));
  417.  
  418.     //Insure all pages are up-to-date.
  419.     m_pPG->FIStorageUpdate(TRUE);
  420.  
  421.     //This also copies the CLSID we stuff in here on file creation.
  422.     hr=m_pIStorage->CopyTo(NULL, NULL, NULL, pIStorage);
  423.  
  424.     if (FAILED(hr))
  425.         {
  426.         pIStorage->Release();
  427.         return DOCERR_WRITEFAILURE;
  428.         }
  429.  
  430.     pIStorage->Commit(STGC_ONLYIFCURRENT);
  431.  
  432.     /*
  433.      * Revert changes on the original storage.  If this was a temp file,
  434.      * it's deleted since we used STGM_DELETEONRELEASE.
  435.      */
  436.     m_pIStorage->Release();
  437.  
  438.     //Make this new storage current
  439.     m_pIStorage=pIStorage;
  440.     m_pPG->FIStorageSet(pIStorage, TRUE, FALSE);
  441.  
  442.     FDirtySet(FALSE);
  443.     Rename(pszFile);    //Update caption bar.
  444.  
  445.     return DOCERR_NONE;
  446.     }
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453. //CHAPTER7MOD
  454.  
  455.  
  456. /*
  457.  * CPatronDoc::FClip
  458.  *
  459.  * Purpose:
  460.  *  Places a private format, a metafile, and a bitmap of the display
  461.  *  on the clipboard, optionally implementing Cut by deleting the
  462.  *  data in the current window after rendering.
  463.  *
  464.  * Parameters:
  465.  *  hWndFrame       HWND of the main window.
  466.  *  fCut            BOOL indicating cut (TRUE) or copy (FALSE).
  467.  *
  468.  * Return Value:
  469.  *  BOOL            TRUE if successful, FALSE otherwise.
  470.  */
  471.  
  472. BOOL CPatronDoc::FClip(HWND hWndFrame, BOOL fCut)
  473.     {
  474.     if (NULL==m_pPG)
  475.         return FALSE;
  476.  
  477.     return m_pPG->TenantClip(fCut);
  478.     }
  479.  
  480.  
  481.  
  482.  
  483.  
  484. /*
  485.  * CPatronDoc::FPaste
  486.  *
  487.  * Purpose:
  488.  *  Retrieves the private data format from the clipboard and sets it
  489.  *  to the current figure in the editor window.
  490.  *
  491.  *  Note that if this function is called, then the clipboard format
  492.  *  is available because the Paste menu item is only enabled if the
  493.  *  format is present.
  494.  *
  495.  * Parameters:
  496.  *  hWndFrame       HWND of the main window.
  497.  *
  498.  * Return Value:
  499.  *  BOOL            TRUE if successful, FALSE otherwise.
  500.  */
  501.  
  502. BOOL CPatronDoc::FPaste(HWND hWndFrame)
  503.     {
  504.     LPDATAOBJECT    pIDataObject;
  505.     BOOL            fRet=FALSE;
  506.     FORMATETC       fe;
  507.     TENANTTYPE      tType;
  508.  
  509.     if (NULL==m_pPG)
  510.         return FALSE;
  511.  
  512.     if (FAILED(OleGetClipboard(&pIDataObject)))
  513.         return FALSE;
  514.  
  515.     //Go get the type and format we *can* paste, then actually paste it.
  516.     if (FQueryPasteFromData(pIDataObject, &fe, &tType))
  517.         fRet=FPasteFromData(pIDataObject, &fe, tType, NULL, 0L);
  518.  
  519.     pIDataObject->Release();
  520.     return fRet;
  521.     }
  522.  
  523.  
  524.  
  525.  
  526. /*
  527.  * CPatronDoc::FQueryPaste
  528.  *
  529.  * Purpose:
  530.  *  Determines if we can paste data from the clipboard.
  531.  *
  532.  * Parameters:
  533.  *  None
  534.  *
  535.  * Return Value:
  536.  *  BOOL            TRUE if data is available, FALSE otherwise.
  537.  */
  538.  
  539. BOOL CPatronDoc::FQueryPaste(void)
  540.     {
  541.     LPDATAOBJECT    pIDataObject;
  542.     BOOL            fRet;
  543.  
  544.     if (FAILED(OleGetClipboard(&pIDataObject)))
  545.         return FALSE;
  546.  
  547.     fRet=FQueryPasteFromData(pIDataObject, NULL, NULL);
  548.     pIDataObject->Release();
  549.     return fRet;
  550.     }
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557. /*
  558.  * CPatronDoc::FPasteSpecial
  559.  *
  560.  * Purpose:
  561.  *  Retrieves a specific data format from the clipboard and sends it to
  562.  *  the editor window appropriately.
  563.  *
  564.  *  Note that if this function is called, then the appropriate format
  565.  *  is available because the Paste menu item is only enabled if the
  566.  *  format is present.
  567.  *
  568.  * Parameters:
  569.  *  hWndFrame       HWND of the main window
  570.  *
  571.  * Return Value:
  572.  *  BOOL            TRUE if successful, FALSE otherwise.
  573.  */
  574.  
  575. BOOL CPatronDoc::FPasteSpecial(HWND hWndFrame)
  576.     {
  577.     OLEUIPASTESPECIAL   ps;
  578.     OLEUIPASTEENTRY     rgPaste[4];
  579.     UINT                uTemp;
  580.     BOOL                fRet=FALSE;
  581.  
  582.     if (NULL==m_pPG)
  583.         return FALSE;
  584.  
  585.     _fmemset(&ps, 0, sizeof(ps));
  586.  
  587.     if (FAILED(OleGetClipboard(&ps.lpSrcDataObj)))
  588.         return FALSE;
  589.  
  590.     ps.cbStruct=sizeof(ps);
  591.     ps.hWndOwner=hWndFrame;
  592.  
  593.     ps.dwFlags=PSF_SELECTPASTE;
  594.  
  595.     ps.arrPasteEntries=rgPaste;
  596.     ps.cPasteEntries=4;
  597.  
  598.     //Set up Paste Special descriptor arrays.
  599.     SETDefFormatEtc(rgPaste[0].fmtetc, m_cf, TYMED_HGLOBAL);
  600.     rgPaste[0].lpstrFormatName=PSZ(IDS_CLIPBOARDFORMAT);
  601.     rgPaste[0].lpstrResultText=PSZ(IDS_PASTEASPATRON);
  602.     rgPaste[0].dwFlags=OLEUIPASTE_PASTEONLY;
  603.  
  604.     SETDefFormatEtc(rgPaste[1].fmtetc, CF_METAFILEPICT, TYMED_MFPICT);
  605.     rgPaste[1].lpstrFormatName=PSZ(IDS_PASTEMETAFILE);
  606.     rgPaste[1].lpstrResultText=PSZ(IDS_PASTEASMETAFILE);
  607.     rgPaste[1].dwFlags=OLEUIPASTE_PASTEONLY;
  608.  
  609.     SETDefFormatEtc(rgPaste[2].fmtetc, CF_DIB, TYMED_HGLOBAL);
  610.     rgPaste[2].lpstrFormatName=PSZ(IDS_PASTEDIB);
  611.     rgPaste[2].lpstrResultText=PSZ(IDS_PASTEASDIB);
  612.     rgPaste[2].dwFlags=OLEUIPASTE_PASTEONLY;
  613.  
  614.     SETDefFormatEtc(rgPaste[3].fmtetc, CF_BITMAP, TYMED_GDI);
  615.     rgPaste[3].lpstrFormatName=PSZ(IDS_PASTEBITMAP);
  616.     rgPaste[3].lpstrResultText=PSZ(IDS_PASTEASBITMAP);
  617.     rgPaste[3].dwFlags=OLEUIPASTE_PASTEONLY;
  618.  
  619.     uTemp=OleUIPasteSpecial(&ps);
  620.  
  621.     if (OLEUI_OK==uTemp)
  622.         {
  623.         fRet=FPasteFromData(ps.lpSrcDataObj, &rgPaste[ps.nSelectedIndex].fmtetc
  624.             , TENANTTYPE_STATIC, NULL, 0L);
  625.         }
  626.  
  627.     ps.lpSrcDataObj->Release();
  628.     return fRet;
  629.     }
  630.  
  631.  
  632.  
  633.  
  634. /*
  635.  * CPatronDoc::FQueryPasteFromData
  636.  * (Protected)
  637.  *
  638.  * Purpose:
  639.  *  Determines if we can paste data from a data object.
  640.  *
  641.  * Parameters:
  642.  *  pIDataObject    LPDATAOBJECT from which we might want to paste.
  643.  *  pFE             LPFORMATETC in which to return the first format
  644.  *                  we can use.  Ignored if NULL.
  645.  *  ptType          LPTENANTTYPE in which to store the type of object we
  646.  *                  can paste.  Ignored if NULL.
  647.  *
  648.  * Return Value:
  649.  *  BOOL            TRUE if data is available, FALSE otherwise.
  650.  */
  651.  
  652. BOOL CPatronDoc::FQueryPasteFromData(LPDATAOBJECT pIDataObject
  653.     , LPFORMATETC pFE, LPTENANTTYPE ptType)
  654.     {
  655.     FORMATETC       fe;
  656.     HRESULT         hr;
  657.  
  658.     if (NULL!=(LPVOID)ptType)
  659.         *ptType=TENANTTYPE_STATIC;
  660.  
  661.     //Any of our specific data here?
  662.     SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
  663.     hr=pIDataObject->QueryGetData(&fe);
  664.  
  665.     if (NOERROR!=hr)
  666.         {
  667.         //Try metafile, DIB, then bitmap, setting fe each time for TenantCreate
  668.         SETDefFormatEtc(fe, CF_METAFILEPICT, TYMED_MFPICT);
  669.         hr=pIDataObject->QueryGetData(&fe);
  670.  
  671.         if (NOERROR!=hr)
  672.             {
  673.             SETDefFormatEtc(fe, CF_DIB, TYMED_HGLOBAL);
  674.             hr=pIDataObject->QueryGetData(&fe);
  675.  
  676.             if (NOERROR!=hr)
  677.                 {
  678.                 SETDefFormatEtc(fe, CF_BITMAP, TYMED_GDI);
  679.                 hr=pIDataObject->QueryGetData(&fe);
  680.                 }
  681.             }
  682.         }
  683.  
  684.     if (NOERROR==hr && NULL!=pFE)
  685.         *pFE=fe;
  686.  
  687.     return (NOERROR==hr);
  688.     }
  689.  
  690.  
  691.  
  692.  
  693.  
  694. /*
  695.  * CPatronDoc::FPasteFromData
  696.  * (Protected)
  697.  *
  698.  * Purpose:
  699.  *  Retrieves the private data format from a data object and sets it
  700.  *  to the current figure in the editor window.
  701.  *
  702.  * Parameters:
  703.  *  pIDataObject    LPDATAOBJECT from which to paste.
  704.  *  pFE             LPFORMATETC to use in the paste. Cannot be NULL.
  705.  *  tType           TENANTTYPE to paste.
  706.  *  ppo             LPPATRONOBJECT containing placement data.
  707.  *  dwData          DWORD extra data sensitive to tType
  708.  *
  709.  * Return Value:
  710.  *  BOOL            TRUE if successful, FALSE otherwise.
  711.  */
  712.  
  713. BOOL CPatronDoc::FPasteFromData(LPDATAOBJECT pIDataObject
  714.     , LPFORMATETC pFE, TENANTTYPE tType, LPPATRONOBJECT ppo, DWORD dwData)
  715.     {
  716.     BOOL            fRet;
  717.     HRESULT         hr;
  718.     PATRONOBJECT    po;
  719.     STGMEDIUM       stm;
  720.  
  721.     if (NULL==pFE)
  722.         return FALSE;
  723.  
  724.     //If we're not given any placement data, see if we can retrieve it
  725.     if (pFE->cfFormat==m_cf && NULL==ppo)
  726.         {
  727.         hr=pIDataObject->GetData(pFE, &stm);
  728.  
  729.         if (SUCCEEDED(hr))
  730.             {
  731.             ppo=(LPPATRONOBJECT)GlobalLock(stm.hGlobal);
  732.  
  733.             po=*ppo;
  734.             ppo=&po;
  735.  
  736.             GlobalUnlock(stm.hGlobal);
  737.             ReleaseStgMedium(&stm);
  738.             }
  739.         }
  740.  
  741.     fRet=m_pPG->TenantCreate(tType, (LPVOID)pIDataObject, pFE, ppo, dwData);
  742.  
  743.     if (fRet)
  744.         {
  745.         //Disable Printer Setup once we've created a tenant.
  746.         m_fPrintSetup=FALSE;
  747.         FDirtySet(TRUE);
  748.         }
  749.  
  750.     return fRet;
  751.     }
  752.  
  753. //End CHAPTER7MOD
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760. /*
  761.  * CPatronDoc::Print
  762.  *
  763.  * Purpose:
  764.  *  Prints the current document.
  765.  *
  766.  * Parameters:
  767.  *  hWndFrame       HWND of the frame to use for dialog parents.
  768.  *
  769.  * Return Value:
  770.  *  BOOL            TRUE if printing happened, FALSE if it didn't start
  771.  *                  or didn't complete.
  772.  */
  773.  
  774. BOOL CPatronDoc::Print(HWND hWndFrame)
  775.     {
  776.     PRINTDLG        pd;
  777.     BOOL            fSuccess;
  778.  
  779.     memset(&pd, 0, sizeof(PRINTDLG));
  780.     pd.lStructSize=sizeof(PRINTDLG);
  781.     pd.hwndOwner  =hWndFrame;
  782.     pd.nCopies    =1;
  783.     pd.nFromPage  =-1;
  784.     pd.nToPage    =-1;
  785.     pd.nMinPage   =1;
  786.     pd.nMaxPage   =m_pPG->NumPagesGet();
  787.  
  788.     //Get the current document printer settings
  789.     pd.hDevMode=m_pPG->DevModeGet();
  790.  
  791.     pd.Flags=PD_RETURNDC | PD_ALLPAGES | PD_COLLATE
  792.         | PD_HIDEPRINTTOFILE | PD_NOSELECTION;
  793.  
  794.     if (!PrintDlg(&pd))
  795.         return FALSE;
  796.  
  797.     //Make sure the Pages knows about any printer changes.
  798.     if (!m_pPG->DevModeSet(pd.hDevMode, pd.hDevNames))
  799.         {
  800.         GlobalFree(pd.hDevMode);
  801.         GlobalFree(pd.hDevNames);
  802.         return FALSE;
  803.         }
  804.  
  805.     //Go do the actual printing.
  806.     fSuccess=m_pPG->Print(pd.hDC, PSZ(IDS_DOCUMENTNAME), pd.Flags
  807.         , pd.nFromPage, pd.nToPage, pd.nCopies);
  808.  
  809.     if (!fSuccess)
  810.         MessageBox(m_hWnd, PSZ(IDS_PRINTERROR), PSZ(IDS_DOCUMENTCAPTION), MB_OK);
  811.  
  812.     return fSuccess;
  813.     }
  814.  
  815.  
  816.  
  817.  
  818.  
  819.  
  820. /*
  821.  * CPatronDoc::PrinterSetup
  822.  *
  823.  * Purpose:
  824.  *  Selects a new printer and options for this document.
  825.  *
  826.  * Parameters:
  827.  *  hWndFrame       HWND of the frame to use for dialog parents.
  828.  *  fDefault        BOOL to avoid any dialog and just use the default.
  829.  *
  830.  * Return Value:
  831.  *  UINT            Undefined
  832.  *
  833.  */
  834.  
  835. UINT CPatronDoc::PrinterSetup(HWND hWndFrame, BOOL fDefault)
  836.     {
  837.     PRINTDLG        pd;
  838.  
  839.     //Attempt to get printer metrics for the default printer.
  840.     memset(&pd, 0, sizeof(PRINTDLG));
  841.     pd.lStructSize=sizeof(PRINTDLG);
  842.  
  843.     if (fDefault)
  844.         pd.Flags=PD_RETURNDEFAULT;
  845.     else
  846.         {
  847.         pd.hwndOwner=hWndFrame;
  848.         pd.Flags=PD_PRINTSETUP;
  849.  
  850.         //Get the current document printer settings
  851.         pd.hDevMode=m_pPG->DevModeGet();
  852.         }
  853.  
  854.     if (!PrintDlg(&pd))
  855.         return FALSE;
  856.  
  857.     if (!m_pPG->DevModeSet(pd.hDevMode, pd.hDevNames))
  858.         {
  859.         GlobalFree(pd.hDevNames);
  860.         GlobalFree(pd.hDevMode);
  861.         return FALSE;
  862.         }
  863.  
  864.     FDirtySet(TRUE);
  865.     return 1;
  866.     }
  867.  
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874. /*
  875.  * CPatronDoc::NewPage
  876.  *
  877.  * Purpose:
  878.  *  Creates a new page in the document's pages control after the
  879.  *  current page.
  880.  *
  881.  * Parameters:
  882.  *  None
  883.  *
  884.  * Return Value:
  885.  *  UINT            Index of the new page.
  886.  */
  887.  
  888. UINT CPatronDoc::NewPage(void)
  889.     {
  890.     FDirtySet(TRUE);
  891.     return m_pPG->PageInsert(0);
  892.     }
  893.  
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900. /*
  901.  * CPatronDoc::DeletePage
  902.  *
  903.  * Purpose:
  904.  *  Deletes the current page from the document.
  905.  *
  906.  * Parameters:
  907.  *  None
  908.  *
  909.  * Return Value:
  910.  *  UINT            Index of the now current page.
  911.  */
  912.  
  913. UINT CPatronDoc::DeletePage(void)
  914.     {
  915.     FDirtySet(TRUE);
  916.     return m_pPG->PageDelete(0);
  917.     }
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925. /*
  926.  * CPatronDoc::NextPage
  927.  *
  928.  * Purpose:
  929.  *  Shows the next page in the pages window.
  930.  *
  931.  * Parameters:
  932.  *  None
  933.  *
  934.  * Return Value:
  935.  *  UINT            Index of the new page.
  936.  */
  937.  
  938. UINT CPatronDoc::NextPage(void)
  939.     {
  940.     UINT        iPage;
  941.  
  942.     iPage=m_pPG->CurPageGet();
  943.     return m_pPG->CurPageSet(++iPage);
  944.     }
  945.  
  946.  
  947.  
  948.  
  949.  
  950.  
  951.  
  952. /*
  953.  * CPatronDoc::PreviousPage
  954.  *
  955.  * Purpose:
  956.  *  Shows the previous page in the pages window.
  957.  *
  958.  * Parameters:
  959.  *  None
  960.  *
  961.  * Return Value:
  962.  *  UINT            Index of the new page.
  963.  */
  964.  
  965. UINT CPatronDoc::PreviousPage(void)
  966.     {
  967.     UINT        iPage;
  968.  
  969.     //If iPage is zero, then we wrap around to the end.
  970.     iPage=m_pPG->CurPageGet();
  971.     return m_pPG->CurPageSet(--iPage);
  972.     }
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979. /*
  980.  * CPatronDoc::FirstPage
  981.  *
  982.  * Purpose:
  983.  *  Shows the first page page in the pages window.
  984.  *
  985.  * Parameters:
  986.  *  None
  987.  *
  988.  * Return Value:
  989.  *  UINT            Index of the new page.
  990.  */
  991.  
  992. UINT CPatronDoc::FirstPage(void)
  993.     {
  994.     return m_pPG->CurPageSet(0);
  995.     }
  996.  
  997.  
  998.  
  999.  
  1000.  
  1001.  
  1002. /*
  1003.  * CPatronDoc::LastPage
  1004.  *
  1005.  * Purpose:
  1006.  *  Shows the last page in the pages window.
  1007.  *
  1008.  * Parameters:
  1009.  *  None
  1010.  *
  1011.  * Return Value:
  1012.  *  UINT            Index of the last page.
  1013.  */
  1014.  
  1015. UINT CPatronDoc::LastPage(void)
  1016.     {
  1017.     return m_pPG->CurPageSet(-1);
  1018.     }
  1019.